// video_trans.c
#include "video_trans.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <ostream>
#include <iostream>

// Define constants
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480
#define DEFAULT_CHANNELS 3
#define FIFO_NAME "/tmp/ffmpeg_fifo"

// Define global variables
int sockfd = -1;
static int TRANS_CONTiNUE = 0;

// Function to initialize the video stream
stream_t *stream_init(struct sockaddr_in *server_info, frame_buf_t *camera_buf,size_t frame_size) {
    stream_t *stream_ptr = (stream_t *)malloc(sizeof(stream_t));
    if (stream_ptr == NULL) {
        perror("Failed to allocate memory for stream_t");
        return NULL;
    }

    stream_ptr->server_info = server_info;

    // Allocate buffer for camera frames
    stream_ptr->camera_buf = camera_buf;
    if (stream_ptr->camera_buf == NULL) {
        perror("Failed to allocate memory for camera buffer");
        free(stream_ptr);
        return NULL;
    }
    stream_ptr->frame_size = frame_size;
    TRANS_CONTiNUE = 1;
    return stream_ptr;
}

// Function to start the stream module
void *stream_start(void *args) {
    stream_t *stream_ptr = (stream_t *)args;

    // 创建命名管道
    if (mkfifo(FIFO_NAME, 0666) == -1 && errno != EEXIST) {
        std::cerr << "Failed to create FIFO: " << strerror(errno) << std::endl;
        return NULL;
    }

    const char* command = "ffmpeg -y -f rawvideo -vcodec rawvideo -s 640x480 -pix_fmt nv12 -r 30 -i " FIFO_NAME " -an -c:v libx264 -pix_fmt yuv420p -f flv rtmp://192.168.43.133:1935/live/streamkey";

    // 打开一个管道用于写入数据到FFmpeg
    FILE* pipe = popen(command, "w");
    if (!pipe) {
        std::cerr << "Failed to open pipe" << std::endl;
        return NULL;
    }

    // 打开命名管道以写入数据
    int fifo_fd = open(FIFO_NAME, O_WRONLY);
    if (fifo_fd == -1) {
        std::cerr << "Failed to open named pipe" << std::endl;
        return NULL;
    }

    size_t frame_size = stream_ptr->frame_size;
    frame_t *frame = (frame_t *)malloc(frame_size);
    frame_buf_t *frame_buf = stream_ptr->camera_buf;

    while(TRANS_CONTiNUE) {
        // 从环形缓冲区获取帧
        frame_buf_pop(frame_buf, frame);

        // 写入一帧数据到命名管道
        ssize_t bytes_written = write(fifo_fd, frame, frame_size);
        if (bytes_written == -1) {
            std::cerr << "Error writing to FIFO: " << strerror(errno) << std::endl;
            break;
        }
    }

    // 关闭命名管道
    close(fifo_fd);

    // 关闭管道
    pclose(pipe);

    // 清理内存
    free(frame);

    // 删除命名管道
    unlink(FIFO_NAME);

    return NULL;
}

// Function to destroy the stream
int stream_destroy(stream_t *stream_ptr) {
    TRANS_CONTiNUE = 0;
    if (stream_ptr) {
        if (stream_ptr->camera_buf) {
            free(stream_ptr->camera_buf);
        }
        free(stream_ptr);
    }

    return 0;
}
